﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MessageWorkflow.Handler;

namespace MessageWorkflow
{
    public static class WorkflowHandlerFactory
    {
        /// <summary>
        /// Creates a new synchronous handler for the method specified
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
            Justification = "Exceptions will be handeled in the callback")]
        public static IWorkflowHandler FromLambda<T>(Action<T> method)
        {
            if (method == null)
                throw new ArgumentNullException("method");

            Func<AsyncCallback, T, IAsyncResult> methodWrapper = (callback, message) =>
            {
                AsyncResult<T> result = new AsyncResult<T>(callback, message); 

                try
                {
                    method(message);

                    result.SetAsCompleted(null, true);
                }
                catch (Exception ex)
                {
                    result.SetAsCompleted(ex, true);
                }

                return result;
            };

            return new DynamicWorkflowHandler<T>(true, methodWrapper);
        }

        /// <summary>
        /// Creates a new async handler for the method specified
        /// </summary>
        public static IWorkflowHandler FromLambdaAsync<T>(AsyncAction<T> method)
        {
            if (method == null)
                throw new ArgumentNullException("method");

            return new DynamicWorkflowHandler<T>(true, (callback, message) =>
            {
                AsyncResult<T> result = new AsyncResult<T>(callback, message);

                method(message,
                    () => result.SetAsCompleted(null, false),
                    ex => result.SetAsCompleted(ex, false));

                return result;
            });
        }
    }
}
